package com.zrkizzy.common.redis.service;

import org.springframework.data.redis.core.script.RedisScript;

import java.util.List;
import java.util.Properties;
import java.util.Set;

/**
 * Redis操作接口
 *
 * @author zhangrongkang
 * @since 2023/3/9
 */
public interface IRedisService {

    /**
     * 设置键值对
     *
     * @param key 键
     * @param value 值
     * @param time 超时时间
     */
    void set(String key, Object value, long time);

    /**
     * 设置键值对（永不过期）
     *
     * @param key 键
     * @param value 值
     */
    void set(String key, Object value);

    /**
     * 获取键值对
     *
     * @param key 键
     * @return 值
     */
    Object get(String key);

    /**
     * 获取指定类型的键值对
     *
     * @param key 键
     * @param clazz 指定类型
     * @return 值
     */
    <T> T get(String key, Class<T> clazz);

    /**
     * 删除键值对操作
     *
     * @param key 键
     * @return 是否删除成功
     */
    Boolean del(String key);

    /**
     * 批量清除指定前缀的Key
     *
     * @param pattern 指定前缀
     */
    void clearKeys(String pattern);

    /**
     * 递减对应Key的值
     *
     * @param key 键
     * @return 递减后的值
     */
    Long decrement(String key);

    /**
     * 递增对应key的值
     *
     * @param key 键
     * @return 递增后的值
     */
    Long increment(String key);

    /**
     * 获取Key值的失效时间
     *
     * @param key 键
     * @return 失效时间（秒）
     */
    Long getExpire(String key);

    /**
     * 判断Redis中是否存在指定键
     *
     * @param key 键
     * @return 对应键是否存在
     */
    Boolean hasKey(String key);

    /**
     * Redis执行Lua脚本
     *
     * @param redisScript Lua脚本
     * @param keyList Redis中Key值队列
     * @param objects 多个参数
     * @return <T> Lua脚本返回值
     */
    <T> T execute(RedisScript<T> redisScript, List<String> keyList, Object... objects);

    /**
     * 获取指定前缀的所有Key
     *
     * @param pattern 指定前缀
     * @return 所有指定前缀开头的key
     */
    Set<String> scanKeys(String pattern);

    /**
     * 获取指定前缀与数量的Key
     *
     * @param pattern 指定前缀
     * @param size 返回key的数量
     * @return 指定数量的Key
     */
    Set<String> scanKeys(String pattern, Integer size);

    /**
     * 将指定集合存储到Redis中并设置有效时间
     *
     * @param key Key
     * @param list 集合
     * @param time 超时时间
     */
    <T> void setList(String key, List<T> list, long time);

    /**
     * 将指定集合存储到Redis中
     *
     * @param key Key
     * @param list 集合
     */
    <T> void setList(String key, List<T> list);

    /**
     * 获取指定集合
     *
     * @param key Key
     * @return 指定集合
     */
    List<Object> getList(String key);

    /**
     * 获取指定类型集合
     *
     * @param key Key
     * @param clazz 集合元素类型
     * @return 指定类型集合
     */
    <T> List<T> getList(String key, Class<T> clazz);

    /**
     * 获取集合指定数据
     *
     * @param key Key
     * @param start 起始位置
     * @param end 结束位置
     * @return 集合数据
     */
    List<Object> getList(String key, int start, int end);

    /**
     * 获取集合数据
     *
     * @param key Key
     * @param start 起始位置
     * @param end 结束位置
     * @param clazz 集合元素类型
     * @return 集合数据
     */
    <T> List<T> getListValues(String key, int start, int end, Class<T> clazz);

    /**
     * 获取指定Key的类型
     *
     * @param key Key
     * @return Key的数据类型
     */
    String type(String key);

    /**
     * 获取数据库大小
     *
     * @return Redis数据库大小
     */
    Object getDataBaseSize();

    /**
     * 获取Redis具体配置信息
     *
     * @param param Redis内容参数
     * @return Redis配置参数
     */
    Properties getProperties(String param);
}